package com.zjt.service.product;

import com.zjt.dao.IBarCodeJobDao;
import com.zjt.dao.brandcategpry.IBrandDao;
import com.zjt.dao.factory.IFactoryInfoDao;
import com.zjt.dao.product.IProductInfoDao;
import com.zjt.dao.product.IQrCodeDao;
import com.zjt.dao.user.IRecordDao;
import com.zjt.entity.BarCodeJob;
import com.zjt.entity.Record;
import com.zjt.entity.brandcategory.Brand;
import com.zjt.entity.factory.FactoryInfo;
import com.zjt.entity.product.ProductInfo;
import com.zjt.entity.product.QrCode;
import com.zjt.entity.resource.ProductResource;
import com.zjt.service.IStaticParameterService;
import com.zjt.utils.DateUtil;
import com.zjt.utils.StringUtil;
import com.zjt.utils.TwoDimensionCode;
import com.zjt.web.api.vo.base.PageVO;
import com.zjt.web.api.vo.base.RecordVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 条形码与二维码验证
 * interface;
 * 条形码：检查productInfo-->物码中心-->入商标库->企业库
 * @author xueyanbeijing
 */
@Component
public class CodeService implements ICodeService {
    private static Logger logger = LoggerFactory.getLogger(CodeService.class);
    private static TwoDimensionCode handler = new TwoDimensionCode();
    private String baseProductUrl = "";
    private static String isEnableFlagY = "Y";
    private static String isEnableFlagN = "N";
    private static String isEnableFlagA = "A";
    private static String codeTypeBarCode = "barcode";
    private static String codeTypeQrCode = "qrcode";
    private static long initQrNum = 10;  //初始化生成十个二维码
    private IProductInfoDao productInfoDao;
    private IStaticParameterService staticParameterService;
    private IRecordDao recordDao;
    private IBrandDao brandDao;
    private IQrCodeDao qrCodeDao;
    private IBarCodeJobDao barCodeJobDao;
    private IFactoryInfoDao factoryInfoDao;

    @Autowired
    public void setFactoryInfoDao(IFactoryInfoDao factoryInfoDao) {
        this.factoryInfoDao = factoryInfoDao;
    }

    @Autowired
    public void setBarCodeJobDao(IBarCodeJobDao barCodeJobDao) {
        this.barCodeJobDao = barCodeJobDao;
    }

    @Autowired
    public void setProductInfoDao(IProductInfoDao productInfoDao) {
        this.productInfoDao = productInfoDao;
    }
    @Autowired
    public void setStaticParameterService(IStaticParameterService staticParameterService) {
        this.staticParameterService = staticParameterService;
    }
    @Autowired
    public void setRecordDao(IRecordDao recordDao) {
        this.recordDao = recordDao;
    }
    @Autowired
    public void setBrandDao(IBrandDao brandDao) {
        this.brandDao = brandDao;
    }
    @Autowired
    public void setQrCodeDao(IQrCodeDao qrCodeDao) {
        this.qrCodeDao = qrCodeDao;
    }
    private void loadProductImageUrl(String paramterName)
    {
        try
        {
            baseProductUrl = this.staticParameterService.getParameterValueByName(paramterName).trim();
        }catch (Exception e){
            logger.error("取常量表异常");
        }
    }
    @Override
    public RecordVO validateByBarCode(String barCode,String type,long userId) {
        // 会联动从国家物码中心读取数据
        //TODO 检查  productInfo表中有没有，如果有，则直接返回
        ProductInfo productInfo  = this.productInfoDao.findByCodeValueOrGtin(barCode.trim(), barCode.trim());
        RecordVO recordVO = new RecordVO();
        ProductResource productResource = null;
        String goodsPicUrl=null,goodsBigPicUrl=null,goodDesc = "",goodsTitle="";// 默认的白图片
        String brandName = "" ;//商标名称
        int completeFlag = -3;//-3（两者都没有）,-2（无名称，有企业信息）,-1（无企业，有名称信息），1（名称和企业都有）
        this.loadProductImageUrl("productImageUrl");   //取默认目录
        long productId = -1;
        long searchNum = 0;
        int codeValueStatus = -1;
        Brand tempBrand = null;
        if (productInfo!=null)
        {
            codeValueStatus = productInfo.getCodeValueStatus();
            if (productInfo.getBrandId()>0)
            {
                tempBrand = this.brandDao.findOne(productInfo.getBrandId());
                brandName = tempBrand.getChName();
            }
                productId = productInfo.getId();

            //TODO 小图与大图的地址获取：
            if (productInfo.getSmallPicture()!=null&&productInfo.getSmallPicture().length()>0)
            {
                goodsPicUrl = productInfo.getSmallPicture();   //还未完成，需要建立一个函数，形成文件名在后面增加一个big  small等。
                goodsPicUrl = baseProductUrl + goodsPicUrl;
            }
            if (productInfo.getBigPicture()!=null&&productInfo.getBigPicture().length()>0)
            {
                goodsBigPicUrl = productInfo.getBigPicture();
                goodsBigPicUrl = baseProductUrl + goodsBigPicUrl;
            }

            //goodtitle  产品名称，厂家名称，扫描时间
            //goodsdesc  产品条码，产品商标，商品规格，产品短描述，厂家地址
            //TODO  如果productInfo.getDescription() 不存在，则取 企业相关信息作为描述：
            //goodtitles
            //第一行
            if (productInfo.getItemName()!=null&&productInfo.getItemName().trim().length()>0)
                goodsTitle = StringUtil.subString(productInfo.getItemName(),13)+"\n";
            else
                goodsTitle = productInfo.getCodeValue()+"\n";

            FactoryInfo tempFactoryInfo = null;
            if (tempBrand!=null&&tempBrand.getFactoryId()>0)//确保商标存在。
            {
                if(brandName!=null&&brandName.length()>0)
                    goodDesc = "商标:" +brandName+"\n";//商标
                tempFactoryInfo = this.factoryInfoDao.findOne(tempBrand.getFactoryId());
                if (tempFactoryInfo!=null)
                    //第二行
                    goodsTitle = goodsTitle + StringUtil.subString(tempFactoryInfo.getChName(), 13)+"\n";
            }

            if (productInfo.getSpecification()!=null&&productInfo.getSpecification().trim().length()>0)
                goodDesc = goodDesc + "规格:" +productInfo.getSpecification()+"\n";
            if (productInfo.getShortDescription()!=null&&productInfo.getShortDescription().trim().length()>0)
                goodDesc = goodDesc + "描述:" +productInfo.getShortDescription()+"\n";
            if (tempFactoryInfo!=null)
                goodDesc = goodDesc + "地址:" + tempFactoryInfo.getAddress();

        }
        Record temp = null;
        if (productId!=-1)
            temp = this.recordDao.findByUserIdAndCodeValue(userId,barCode.trim());
        //TODO 写入扫描记录
        Record saveRecord = new Record();
        saveRecord.setUserId(userId);
        saveRecord.setCodeType(codeTypeBarCode);
        saveRecord.setCodeValue(barCode);
        saveRecord.setGoodsReal(-1);
        saveRecord.setCreateDate(DateUtil.getCurrentDate());
        saveRecord.setEnableFlag("Y");
        saveRecord.setUpdateDate(DateUtil.getCurrentDate());
        saveRecord.setProductId(productId);
        if (temp!=null&&temp.getId()>0)   //TODO如果存在，则更新
        {
            saveRecord.setId(temp.getId());
            saveRecord.setTotal(temp.getTotal()+1);
            searchNum = temp.getTotal()+1;
        }else
        saveRecord.setTotal(1);

        saveRecord = this.recordDao.save(saveRecord);

        logger.info("写入新的扫描记录:saveRecord="+saveRecord.toString());
        long recordId = 0;
        if (saveRecord.getId()>0) recordId = saveRecord.getId();

        if (productInfo!=null&&saveRecord.getId()>0)//存在
        {
            try{
                recordVO.setCodeType(codeTypeBarCode);
                recordVO.setFirstSearchTime(DateUtil.getDayStr(DateUtil.getCurrentDate(), "yyyy-MM-dd HH:mm:ss"));
                recordVO.setGoodsBigPicUrl(goodsBigPicUrl);
                recordVO.setGoodsDesc(goodDesc);
                recordVO.setGoodsPicUrl(goodsPicUrl);
                recordVO.setGoodsReal(-1);
                recordVO.setGoodsTitle(goodsTitle);
                recordVO.setRecordId(recordId);
                recordVO.setSearchNum(searchNum);
                recordVO.setProductId(productId);
                recordVO.setCodeValue(barCode);
                recordVO.setCodeValueStatus(codeValueStatus);
            }catch (Exception e){
                logger.info("已取到扫描记录异常:");
            }
       }//TODO 如果真假通主数据库中无信息，则加入条码任务列表库，由定时器自动采集
        else //TODO 如果数据库中无此条形码信息  由启动条形码采集程序，将物码中心数据入库，并返回recordVO
        {
            BarCodeJob tempBarcodeJob = null;
                tempBarcodeJob = this.barCodeJobDao.findByCodeValue(barCode);
            BarCodeJob barCodeJob= new BarCodeJob();
            barCodeJob.setCodeType(type);// ean-13
            barCodeJob.setCodeValue(barCode);
            barCodeJob.setStatus(0);
            barCodeJob.setUserId(userId);
            barCodeJob.setCreateDate(DateUtil.getCurrentDate());
            barCodeJob.setEnableFlag("Y");
            barCodeJob.setCompleteFlag(completeFlag);
            barCodeJob.setUpdateDate(DateUtil.getCurrentDate());
            if (tempBarcodeJob!=null)
            {
                barCodeJob.setId(tempBarcodeJob.getId());
                barCodeJob.setStatus(tempBarcodeJob.getStatus());
                barCodeJob.setCreateDate(tempBarcodeJob.getCreateDate());
            }
            this.barCodeJobDao.save(barCodeJob);
        //TODO 构造返回对像
            try{
                recordVO.setCodeType(codeTypeBarCode);
                recordVO.setFirstSearchTime(DateUtil.getDayStr(DateUtil.getCurrentDate(), "yyyy-MM-dd HH:mm:ss"));
                recordVO.setGoodsBigPicUrl(goodsBigPicUrl);
                recordVO.setGoodsDesc(goodDesc);
                recordVO.setGoodsPicUrl(goodsPicUrl);
                recordVO.setGoodsReal(-1);
                recordVO.setGoodsTitle(goodsTitle);
                recordVO.setRecordId(recordId);
                recordVO.setSearchNum(searchNum);
                recordVO.setProductId(productId);
                recordVO.setCodeValue(barCode);
                recordVO.setCodeValueStatus(codeValueStatus);//默认为0
            }catch (Exception e1){
                logger.info("构造返回对像异常:");
            }
         }
        return recordVO;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public RecordVO validateByQrCode(String qrCode,long userId) {
        //不管验证后是真还是假，都将写入扫描记录
        QrCode qrCode1  = this.qrCodeDao.findByCodeValue(qrCode);
        RecordVO recordVO = new RecordVO();
        //二维码是否存在？
        //TODO 存在，并且有效，则返回真 ,返回真后，则需要将此二维码置为已查询过，每条二维码只能查询一次
        Integer isReal = -10;
        ProductInfo productInfo = null;
        ProductResource productResource = null;
        String[] qrcodeArray = qrCode.split("^");
        long searchNum = 0;
        long productId = -1;
        this.loadProductImageUrl("productImageUrl");   //取默认目录
        String  goodsPicUrl=null,goodsBigPicUrl=null;// 默认的白图片
        String brandName = "",goodDesc = "",goodsTitle = "该二维码不是真假通类型";
        if (qrCode1!=null)
        {
            if (qrCode1.getTotal()==1)//
                    isReal = 2;// // 失效 被检验过
            //返回真
            if(qrCode1.getEnableFlag().equalsIgnoreCase(isEnableFlagY))
            {
                isReal = 1;
                qrCode1.setEnableFlag(isEnableFlagN);//置为已被查询过；
                qrCode1.setTotal(1);
                this.qrCodeDao.saveAndFlush(qrCode1);
            }
            else if (qrCode1.getEnableFlag().equalsIgnoreCase(isEnableFlagA))
               isReal = -1;
            else isReal = 2;// 失效 被检验过
        //TODO 存在，但无效，则返回未实现真假通防伪。 -2
        productInfo = this.productInfoDao.findOne(qrCode1.getProductId());
        }else  //TODO 不存在 规则符合真假通规则，则说明是假冒真假通
        {
            // 2被查询过，1是(数据库中有真假通二维码),0否（别人模仿真假通二维码检验，但码值不对，规则符合，但产品ID不存在），-1  未实现真假通防伪（条形码） -2 不可识别的二维码
             //真假通二维码规则     brandname^itemname^specification^barcode^prodcutId(16)^zjt
            //TODO 不存在，规则也不符合真假通规则，则说明是不可识别的二维码，仅显示二维码实际值,并提示用户，此二维码无效，该产品未实现真假通防伪
            try
            {
                int lengthValue = qrcodeArray.length;
                if (qrcodeArray[lengthValue-1].equalsIgnoreCase("zjt"))//说明有可能模仿真假通
                {
                    long tempProductId = Long.parseLong(qrcodeArray[lengthValue-2].toString().trim());
                    if (this.productInfoDao.findOne(tempProductId)!=null)
                        isReal = 0 ;
                    else
                        isReal = -2;
                }
                else isReal = -2;//不可识别
            }   catch (Exception e1){
           }
        }
        //TODO 构造返回对像和写入扫描记录
        Brand tempBrand = null;
        if (productInfo!=null)
        {
            if (productInfo.getBrandId()>0)
            {
                tempBrand = this.brandDao.findOne(productInfo.getBrandId());
                brandName = tempBrand.getChName();
            }
            //TODO 小图与大图的地址获取：
            if (productInfo.getSmallPicture()!=null&&productInfo.getSmallPicture().length()>0)
            {
                goodsPicUrl = productInfo.getSmallPicture();   //还未完成，需要建立一个函数，形成文件名在后面增加一个big  small等。
                goodsPicUrl = baseProductUrl + goodsPicUrl;
            }
            if (productInfo.getBigPicture()!=null&&productInfo.getBigPicture().length()>0)
            {
                goodsBigPicUrl = productInfo.getBigPicture();
                goodsBigPicUrl = baseProductUrl  + goodsBigPicUrl;
            }
            productId = productInfo.getId();

            //TODO  如果productInfo.getDescription() 不存在，则取 企业相关信息作为描述：
            //第一行
            if (productInfo.getItemName()!=null&&productInfo.getItemName().length()>0)
                goodsTitle = StringUtil.subString(productInfo.getItemName(),13)+"\n";

            FactoryInfo tempFactoryInfo = null;
            if (tempBrand!=null&&tempBrand.getFactoryId()>0)//确保商标存在。
            {
                if(brandName!=null&&brandName.length()>0)
                    goodDesc = "商标:" +brandName+"\n";//商标
                tempFactoryInfo = this.factoryInfoDao.findOne(tempBrand.getFactoryId());
                if (tempFactoryInfo!=null)
                    //第二行
                    goodsTitle = goodsTitle +  StringUtil.subString(tempFactoryInfo.getChName(), 13)+"\n";
            }

            if (productInfo.getSpecification()!=null&&productInfo.getSpecification().trim().length()>0)
                goodDesc = goodDesc + "规格:" +productInfo.getSpecification()+"\n";
            if (productInfo.getShortDescription()!=null&&productInfo.getShortDescription().trim().length()>0)
                goodDesc = goodDesc + "描述:" +productInfo.getShortDescription()+"\n";
            if (tempFactoryInfo!=null)
                goodDesc = goodDesc + "地址:" + tempFactoryInfo.getAddress();


        }
        //TODO 正式写扫描记录
        Record temp = null;
        if (productId!=-1)
            temp = this.recordDao.findByUserIdAndCodeValue(userId,qrCode);
        Record record = new Record();
        try{
            record.setUserId(userId);
            record.setCodeType(codeTypeQrCode);
            record.setCodeValue(qrCode);
            record.setGoodsReal(isReal);
            record.setCreateDate(DateUtil.getCurrentDate());
            record.setEnableFlag("Y");
            record.setUpdateDate(DateUtil.getCurrentDate());
            record.setProductId(productId);
            logger.info("二维码：正式写扫描记录:record=" + record.toString());
            if (temp!=null&&temp.getId()>0)   //TODO如果存在，则更新
            {
                record.setId(temp.getId());
                record.setTotal(temp.getTotal()+1);
                searchNum = temp.getTotal()+1;
            } else
            record.setTotal(1);
            record = this.recordDao.saveAndFlush(record);
        }catch (Exception e){
            logger.info("二维码正式写扫描记录异常="+e.getMessage()+"\n");
        }

        //TODO 构造返回对像
        try
        {
            recordVO.setCodeType(codeTypeQrCode);
            recordVO.setFirstSearchTime(DateUtil.getDayStr(record.getUpdateDate(), "yyyy-MM-dd HH:mm:ss"));
            recordVO.setGoodsBigPicUrl(goodsBigPicUrl);
            recordVO.setGoodsDesc(goodDesc);
            recordVO.setGoodsPicUrl(goodsPicUrl);
            recordVO.setGoodsReal(isReal);
            recordVO.setGoodsTitle(goodsTitle);
            recordVO.setRecordId(record.getId());
            recordVO.setSearchNum(searchNum);
            recordVO.setProductId(productId);
            recordVO.setCodeValue(qrCode);
            logger.info("构造返回对像:recordVO="+recordVO.toString());
        }catch (Exception e1){
             logger.error("构造返回对像异常:="+e1.getMessage()+recordVO.toString());
        }
        return recordVO;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public boolean encoderQRCode(ProductInfo productInfo,long qrNum) {
        //真假通二维码规则   qrNum^itemname^prodcutId(16)^zjt
        boolean doFlag = false;
        String codeValue = "0^zjt";
        long productId = -1,productMaxIndex = -1;//产品库中表保存二维码中的最大ID值

        for(long i=0;i<qrNum;i++)
        {
            if (productInfo!=null&&productInfo.getId()>0)
            {
                codeValue = productInfo.getId().toString();
                codeValue = codeValue +  "^zjt";
                codeValue = i + "^"+ codeValue ;
                codeValue = DateUtil.getCurrentDateStr("yyyyMMddHHmmssSSS") + "^"+ codeValue ;
                productId = productInfo.getId();
            }else break;//id 不存在，不生成
            //TODO 给二维码数据库写入新记录
           //TODO 如果没有生成过，则需要重新写入二维码库
            QrCode qrCode = new QrCode();
                try
                {
                    qrCode.setEnableFlag(isEnableFlagY);
                    qrCode.setCodeType(codeTypeQrCode);
                    qrCode.setCodeValue(codeValue);
                    qrCode.setDescription("qrNum^itemname^prodcutId(16)^zjt");
                    qrCode.setProductId(productId);
                    qrCode.setCreateDate(DateUtil.getCurrentDate());
                    qrCode.setUpdateDate(DateUtil.getCurrentDate());
                    qrCode.setTotal(0);
                    qrCode.setHasToPng(0);
                    qrCode = this.qrCodeDao.saveAndFlush(qrCode);
                    doFlag = true;
                    productMaxIndex = qrCode.getId();
                }catch (Exception e){
                    logger.error("更新模式异常:"+qrCode.toString());
                    doFlag = false;
                }
        }//end for


        //TODO 同步刷新  productInfo中的productmaxindex值;
        try
        {
            productInfo.setProductMaxIndex((int)productMaxIndex);
            this.productInfoDao.saveAndFlush(productInfo);
            doFlag = true;
        }catch (Exception e1){
            doFlag = false;
        }
        return doFlag;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void encoderQRCode(List<ProductInfo> list) {
        try
        {
            if (list!=null&&list.size()>0)
            {
                for(ProductInfo productInfo:list)
                {
                    this.encoderQRCode(productInfo,initQrNum);
                }
            }
        }catch (Exception e){

        }
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void encoderQRCodeAll() {
        List<ProductInfo> list = (List<ProductInfo>)this.productInfoDao.findAll();
        if (list!=null&&list.size()>0)
        {
            for(ProductInfo productInfo:list)
            {
                try{
                    this.encoderQRCode(productInfo,initQrNum);
                }catch (Exception e){
                }
            }
        }
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void QrCodeToPng(String content,String productQRPath) {
        try
        {
            String pngName = DateUtil.getCurrentDateStr("yyyyMMddHHmmssSSS")+".png";
            String imgPath = productQRPath +  pngName;
            handler.encoderQRCode(content, imgPath, "png");
           // logger.info("成功生成二级码图片"+content+":imgPath:"+imgPath);
        }catch (Exception e){
            logger.error("handler.encoderQRCode exception");
        }
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public List<QrCode> getQrCodeList(PageVO pageVO) {
        Sort.Direction direction =  Sort.Direction.DESC;
        PageRequest pageRequest = new PageRequest(pageVO.getPageNo(),pageVO.getPageSize(),direction,"id");
        Page<QrCode> list = this.qrCodeDao.findByHasToPng(0,pageRequest);
        List<QrCode> returnList = new ArrayList<QrCode>();
        if (list!=null&&list.getNumberOfElements()>0)
        {
            for (QrCode qrCode:list)
            {
                returnList.add(qrCode);
            }
        }
        return returnList;  //To change body of implemented methods use File | Settings | File Templates.
    }

}
